HTTP Parameter Pollution describes the set of techniques used for manipulating how a server handles parameters in an HTTP request. This vulnerability may occur when duplicating or additional parameters are injected into an HTTP request and the website trusts them. Usually, HPP (HTTP Parameter Pollution) vulnerabilities depend on the way the server-side code handles parameters.
You send the server unexpected data, trying to make the server give an unexpected response. A simple example could be a bank transfer.
Suppose, your bank performs transfers on its website through the use of HTTP parameters. These could be a recipient=
parameter for the receiving party, an amount=
parameter for the amount to send in a specific currency, and a sender=
parameter for the one who sends the money.
A URL for such a transfer could look like the following:
https://www.bank.com/transfer?sender=abcdef&amount=1000&recipient=ghijkl
It may be possible that the bank server assumes it will only ever receive a single sender=
parameter, however, submitting two such parameters (like in the following URL), may result in unexpected behaviour:
https://www.bank.com/transfer?sender=abcdef&amount=1000&recipient=ghijkl&sender=ABCDEF
An attacker could send such a request in hopes that the server will perform any validations with the first parameter and actually transfer the money from the second account specified. When different web servers see duplicate parameters, they handle them in different ways.
Even if a parameter isn't sent through the URL, inserting additional parameters may still cause unexpected server behaviour. This is especially the case with server code which handles parameters in arrays or vectors through indices. Inserting additional parameters at different places in the URL may cause reordering of the array values and lead to unexpected behaviour.
An example could be the following:
https://www.bank.com/transfer?amount=1000&recipient=ghijkl
The server would deduce the sender on the server-side instead of retrieving it from an HTTP request.
Normally, you wouldn't have access to the server code, but for a POC I have written a simple server in a pseudo-code (no particular language).
sender.id = abcdef
function init_transfer(params)
{
params.push(sender.id) // the sender.id should be inserted at params[2]
prepare_transfer(params)
}
function prepare_transfer(params)
{
amount = params[0]
recipient = params[1]
sender = params[2]
transfer(amount, recipient, sender)
}
Two functions are created here, init_transfer
and prepare_transfer
which takes a params
vector. This function also later invokes a transfer
function, the contents of which are currently out of scope. Following the above URL, the amount
parameter be 1000, the recipient would be ghijkl
. The init_transfer
function adds the sender.id
to the parameter array. Note, that the program expects the sender ID to be the 3rd (2nd index) parameter in the array in order to function properly. Finally, the transfer params array should look like this: [1000, ghijkl, abcdef]
.
Now, an attacker could make a request to the following URL:
https://www.bank.com/transfer?amount=1000&recipient=ghijkl&sender=ABCDEF
In this case, sender=
would be included into the parameter vector in its initial state (before the init_transfer
function is invoked). This means that the params
array would look like this: [1000, ghijkl, ABCDEF]
. When init_transfer
is called, the sender.id
variable would be appended to the vector and so it would look like this: [1000, ghijkl, ABCDEF, abcdef]
. Unfortunately, the server still expects that the correct sender would be located at params[2]
, but that is no longer the case since we managed to insert another sender. As such, the money would be withdrawn from ABCDEF
and not abcdef
.
These vulnerabilities allow the attacker to inject extra parameters in order to alter the client-side. An example of this is included in the following presentation: https://owasp.org/www-pdf-archive/AppsecEU09_CarettoniDiPaola_v0.8.pdf.
The example URL is
http://host/page.php?par=123%26action=edit
The example server code is the following:
<? $val=htmlspecialchars($_GET['par'],ENT_QUOTES); ?>
<a href="/page.php?action=view&par='.<?=$val?>.'">View Me!</a>
Here, a new URL is generated based on the value of a parameter $val
. Here, the attacker passes the value 123%26action=edit
onto the parameter. The URL-encoded value for &
is %26
. When this gets to the htmlspecialchars
function, the %26
gets converted to an &
. When the URL gets formed, it becomes
<a href="/page.php?
action=view&par=123&action=edit">
And since this is view as HTML, an additional parameter has been smuggled! The link would be equivalent to
/page.php?
action=view&par=123&action=edit
This second action parameter could cause unexpected behaviour based on how the server handles duplicate requests.